import { ref, computed, watch, toRaw } from 'vue'
import { defineStore, storeToRefs } from 'pinia'
import { getUrlSign } from '@/api'
import { invokeAsyncAPi } from '@/utils/xz-fn'
import {getRealSizeByStr ,getFileSizeStr,getNeedTime} from '@/utils'
import { useDownloadPath } from '@/stores/download-path'
import { useDownloadManageWindow } from '@/stores/download-manage-window'
import { downingListDB, downloadFinishDB } from '@/db/downloadManage'
import { useUserInfo } from '@/stores/user-info'
import useFakeDownloadHook from '@/hooks/use-fake-download-hook'
import useDialogPromiseHook from '@/hooks/use-dialog-promise-hook'
import { useFakeDownload} from '@/stores/fake-download'

// 配置数据
export const useDownloadManage = defineStore('downloadManage', () => {
  const downingRedFlag = ref(false);//是否有东西在下载，红色提示，外面的红点。
  const downloadFinishRedFlag = ref(false);//是否下载完成，红色提示，下载完成的红点
  const downingShowTip = ref(false);//下载显示提示，外面的提示，只有第一次的时候才提示
  const downingShowTipIsFirst = ref(!!!localStorage.getItem('downingShowTipHasShow'));//下载提示，当前是否是第一次。
  
  const fakeDownloadStore = useFakeDownload();
  const { showDialog,closeDialogTime}=storeToRefs(fakeDownloadStore)

  const downingList = ref<any[]>([]);//正在下载的list
  
  const finishList = ref<any[]>([]);//下载完成的list

  const downloadPathStore = useDownloadPath();
  const { downloadPath } = storeToRefs(downloadPathStore)
  
  const downloadManageWindowStore = useDownloadManageWindow();
  const { masterWindowId, downloadManageWindowId, downloadFinishWindowId } = storeToRefs(downloadManageWindowStore)
  
  const userInfoStore = useUserInfo();
  const { isMember } = storeToRefs(userInfoStore)
  const dialog = useDialogPromiseHook();
  
  // watch(isMember, (value) => {//is memeber变化，重新下载
  //   clearAllDowning();
  //   startAllDowningListItem();
  // })

  const maxDownloadSize = 5;//最大下载多少个

  const fakeDownloadInstance = useFakeDownloadHook();
  
  const addToDowningList = async (item: any) => {//加入下载列表

    let exitItemHistory = finishList.value.find(item1 => item1.url === item.url);
    if (exitItemHistory) {
      const exit = await invokeAsyncAPi('fq_PathFileExists', exitItemHistory.downloadFullPath)
      if (!exit) {//文件不存在，
        exitItemHistory = null;
      }
    }
    const exitItem = downingList.value.find(item1 => item1.url === item.url);
    if (exitItem || exitItemHistory) {
      if (exitItem) {
        startItem(exitItem.id);//启动下载，因为可能处于暂停状态
      }
      dialog.showDialog('dialogSimple', {
        content: exitItem?'该文件正在下载中\n可以在下载中心进行查看':'该文件已经下载完成\n可以在下载记录中查看',
        buttonList: [
          {
            text: '查看详情',
            click: 'success',
            type: 'primary'
          },
          {
            text: '取消',
            click: 'cancel',
            type: 'default'
          }
        ]
      }).then(() => {
        downloadManageWindowStore.openDownloadManageWindow(exitItem?'1':'2');
      })
        .catch(() => { })
      return;
    } 
    else {
      dialog.showDialog('dialogSimple', {
        content: '已添加至下载列表',
        buttonList: [
          {
            text: '查看详情',
            click: 'success',
            type: 'primary'
          },
          {
            text: '取消',
            click: 'cancel',
            type: 'default'
          }
        ]
      })
        .then(() => {
          downloadManageWindowStore.openDownloadManageWindow('1');
      })
      .catch(() => {})
    }
   
    // const oldDowningList=[...toRaw(downingList.value)]
    const obj = {
      status: '0',//0等待下载，1下载中，2下载完成，3下载失败，4暂停，5下载请求中，6.下载请求中(fake专用，停了就是6)；在fake里面，有0，1，4，6
      errorMsg: '',//失败原因
      
      allSize: getRealSizeByStr(item.size),
      allSizeStr: item.size,
      
      title:item.file_name,
      icon: item.icon,
      sign_type: item.sign_type,//签名类型
      
      needTime:0,
      needTimeStr:'-- : -- : --',
      downloadSpeed:0,
      downloadSpeedStr:'0KB',
      currentSize:0,
      currentSizeStr: '0KB',
      percent: 0,
      
      id: Math.random().toString(36).slice(2)+(new Date()).getTime().toString(36),
      createTime: (new Date()).getTime(),
      downloadId: '',//下载id,控制下载的
      downloadRealId: '',
      downloadPath: downloadPath.value,//下载目录
      downloadFullPath:'',//下载完整路径
      realUrl: '',
      url:item.url,
      md5: item.md5,
      fake_start_time: (new Date()).getTime(),//假下载的开始时间，用来弹框
      fake_time_out: (5 + 5 * Math.random()) * 1000,//间隔5-10s
    }
    downingList.value.push(obj)
    downingListDB.add({...obj})
    // downingList.value = oldDowningList;

    downingRedFlag.value = true;
    if (downingShowTipIsFirst.value) {
      downingShowTip.value = true;
      setTimeout(() => {
        downingShowTip.value = false;
      },5000)
    }
    startItem(obj.id);
  }

  const startItem = async (id: string) => {//开始任务
    
    const item = downingList.value.find(item => item.id === id);
    if (isMember.value) {//是会员
      /**
       * 等待下载（1.add时候，2.自动append，3.界面无法点击,4.全部开始)
       * 失败(1.不自动append，2.界面点击,3.全部开始)
       * 暂停(1.不自动append, 2.界面点击,3.全部开始)
       */
      if (['4', '0', '3'].includes(item.status)) {
        const isRunCount = downingList.value.filter(item => ['1', '5'].includes(item.status)).length;
        if (isRunCount >= maxDownloadSize) {//正在下载的超过5个，不能下载，变成等待下载
          item.status = '0'
          item.needTime = 0;
          item.needTimeStr = '-- : -- : --';
          downingListDB.put({ ...toRaw(item) })
          return ;
        }
        item.status = '5'
        await _getRealUrl(item);//获取真实url
        await _createDownloadId(item);//创新下载实例
        _startDownload(id);//开始下载
      }
    } else {//创建要给fake id
      if (item.status==='3') {//失败，弹出个人中心
        invokeAsyncAPi('fq_ShowUserCenter')
      }
      if (['4', '0'].includes(item.status)) {
        const isRunCount = downingList.value.filter(item => ['1'].includes(item.status)).length;
        if (isRunCount >= maxDownloadSize) {//正在下载的超过5个，不能下载，变成等待下载
          item.status = '0'
          item.needTime = 0;
          item.needTimeStr = '-- : -- : --';
          downingListDB.put({ ...toRaw(item) })
          return ;
        }
        if (!item.downloadId) {
          item.downloadId = fakeDownloadInstance.initOne(item);
        }
        item.fake_start_time = (new Date()).getTime();
        item.fake_time_out = (5 + 5 * Math.random()) * 1000;
        fakeDownloadInstance.startOne(item.downloadId, async () => {
          if (item.status === '4') {
            fakeDownloadStore.setShowDialog(true);
            if (downloadManageWindowId.value) {
              downloadManageWindowStore.openDownloadManageWindow();
              invokeAsyncAPi('fq_NotifyWebMessageEx', downloadManageWindowId.value, 'download-user-overload',item.id);
            } else {
              const status = await downloadManageWindowStore.getMasterWindowStatus();
              if ([2, 3].includes(status)) {//窗口隐藏，或者最小化
                downloadManageWindowStore.openUserOverLoadWindow(item.id);
              } else {
                dialog.showDialog('userOverload').then((value) => {
                  invokeAsyncAPi('fq_ShowUserCenter')
                  startItem(item.id)
                  fakeDownloadStore.setShowDialog(false);
                }).catch((value) => {
                  if (value === 'member') {
                    // invokeAsyncAPi('fq_ShowUserCenter')
                     invokeAsyncAPi('fq_NotifyWebMessageEx', masterWindowId.value, 'change-member-state')
                    // startItem(item.id)
                  }
                  fakeDownloadStore.setShowDialog(false);
                })
              }
            }
            
          }else if(item.status==='3'){
            finishDowningItem({
              id: item.downloadId,
              file: '',
              ret:1
            })
          }
          downingListDB.put({ ...toRaw(item) })
        })
      }
    }
  }

  const _getRealUrl= async (item:any) => {//获取真实下载链接
    // const oldDowningList = [...toRaw(downingList.value)]
    if (item) {
      //获取真实url
      const {code,data} = await getUrlSign({
        url: item.url,
        type:item.sign_type,
      })
      if (code === 200) {
        item.realUrl = data.url;//真实url
      } 
      downingListDB.put({ ...toRaw(item) })
    }
    
  }

  const _startDownload = (id: string) => {//开始下载
    const item = downingList.value.find(item => item.id === id);
    if (item&&['5'].includes(item.status)) {
      item.status = '1';
      invokeAsyncAPi('fq_ctrl_download', {
        id: item.downloadId,
        url:item.realUrl,
        flag:0,
      })
      downingListDB.put({ ...toRaw(item) })
    }
  }

  const stopItem = (id: string,isAllStop:boolean) => {//暂停任务
   
    const item = downingList.value.find(item => item.id === id);
    if (isAllStop && item.status === '0') {//全部暂停的时候，把等待下载也暂停。
      item.status = '4';
      downingListDB.put({ ...toRaw(item) })
      return;
    }
    if (isMember.value) {
      if (item && ['1', '5'].includes(item.status)) {
        item.status = '4';
        item.needTime = 0;
        item.needTimeStr = '-- : -- : --';
        invokeAsyncAPi('fq_ctrl_download', {
          id: item.downloadId,
          url:item.realUrl,
          flag:1,
        })
        downingListDB.put({ ...toRaw(item) })
        if (!isAllStop) {//整体停止的话，不好自动播放下一个
          autoAppend();
        }
        
      }
    } else {
      if (item && ['1'].includes(item.status)) {
        item.status = '4';
        item.needTime = 0;
        item.needTimeStr = '-- : -- : --';
        fakeDownloadInstance.pauseOne(item.downloadId)
        downingListDB.put({ ...toRaw(item) })
        if (!isAllStop) {//整体停止的话，不好自动播放下一个
          autoAppend();
        }
      }
    }
    
  }

  const getRetMsg = (ret:number) => {
    if (ret === 1) {
      return '网络故障，请检查网络'
    } else if (ret === 2) {
      return '磁盘空间不足'
    } else if (ret === 3) {
      return '权限不足'
    } else if (ret === 4) {
      return '下载文件hash校验失败'
    } else {
      return '网络故障，请检查网络'
    }
  }

  const _createDownloadId = async (item: any) => {
    if (item && !item.downloadId) {//没有创建download管理，创建一个
      const obj:any={
        url: item.realUrl,
        file_name: item.title,
        save_path:item.downloadPath,
        hash:item.md5
      }
      if (item.downloadRealId) {//例如从上一次恢复，或者vip切换
        obj.id=item.downloadRealId
      }
      const { id, ret, file_size } = await invokeAsyncAPi('fq_create_download', obj);
      if (id) {
        item.downloadId = id;
        item.downloadRealId = id;
        item.allSize =file_size;
        item.allSizeStr = getFileSizeStr(file_size);
        downingListDB.put({ ...toRaw(item) })
      } else {//失败
        const _key = Math.random().toString(36).slice(2);
        item.downloadId = _key;
        item.status = '3';
        finishDowningItem({
          id: _key,
          file: '',
          ret:ret
        })
      }
    }
  }

  const processDowningItem = (obj: any) => {//更新下载item的进度
    // const oldDowningList = [...toRaw(downingList.value)]
    const item = downingList.value.find(item => item.downloadId === obj.id)
    if (item) {
      item.needTime = obj.remaining_time >> 0
      item.needTimeStr=getNeedTime(item.needTime)
      item.downloadSpeed = obj.speed
      item.downloadSpeedStr=getFileSizeStr(item.downloadSpeed)
      item.currentSize = obj.download_size
      item.currentSizeStr=getFileSizeStr(item.currentSize)
      item.percent = obj.progress
      // downingList.value = oldDowningList;
      downingListDB.put({ ...toRaw(item) })
    }
  }
 function formatTime(timestamp: any) {
	//时间戳为10位需*1000，为13位不需乘1000
	let times: any=null;
    if(timestamp.length==10){
      times=times*1000
    }else {
      times=timestamp
    }
    var date = new Date(times);
    const Y = date.getFullYear(),
        M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1),
        D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()),
        h = (date.getHours() < 10 ? '0' + (date.getHours()) : date.getHours()),
        m = (date.getMinutes() < 10 ? '0' + (date.getMinutes()) : date.getMinutes()),
        s = (date.getSeconds() < 10 ? '0' + (date.getSeconds()) : date.getSeconds());
    return Y + '-' + M + '-' + D + ' ' + h + ':' + m + ':' + s
}
  const finishDowningItem =async (obj: any) => {//下载完成
    // const oldDowningList = [...toRaw(downingList.value)]
    // const oldFinishList = [...toRaw(finishList.value)]
    const item = downingList.value.find(item => item.downloadId === obj.id)
    if (item) {
      item.status = obj.ret === 0 ? '2' : '3';
      
      if (item.status === '3') {//下载失败，
        item.downloadId = '';//特别针对下载失败，需要删除id，然后重新下载
        item.errorMsg = getRetMsg(obj.ret);
        downingListDB.put({ ...toRaw(item) })
      } else {//完成，进入下载列表
        item.downloadFullPath = obj.file ;
        item.finishTime = (new Date()).getTime();
        item.endTime = formatTime((new Date()).getTime());
        item.payTime = (item.finishTime - item.createTime)/1000;//花费时间
        item.payTimeStr = getNeedTime(item.payTime)
        const index = downingList.value.findIndex(item => item.downloadId === obj.id);
        finishList.value.push(item);
        downloadFinishDB.add({ ...toRaw(item) })
        if (index !== -1) {
          downingListDB.delete(item.id)
          downingList.value.splice(index,1)
        }
        downloadFinishRedFlag.value = true;
        autoAppend();
      }

       //如果下载管理打开了，就直接在下载管理弹，否则弹在右小角。
       if (downloadManageWindowId.value) {
        if (item.status==='2') {//下载完成
          //  invokeAsyncAPi('fq_NotifyWebMessageEx', downloadManageWindowId.value, 'download-finish-success', item.title);
        } else if (item.status === '3') {//下载失败
          downloadManageWindowStore.openDownloadManageWindow();
          invokeAsyncAPi('fq_NotifyWebMessageEx', downloadManageWindowId.value, 'download-finish-fail', {
            title:item.title,
            errorMsg:item.errorMsg
          });
        }
      } else {
        if (downingList.value.filter(item => ['1', '5'].includes(item.status)).length === 0) {//能下载的都下载完了
          const status = await downloadManageWindowStore.getMasterWindowStatus();
          if ([2, 3].includes(status)) {//窗口隐藏，或者最小化
            downloadManageWindowStore.openDownloadFinishWindow();
          }
        }
      }
    }
  }

  const autoAppend = () => {//暂停，完成，删除后，自动下载等待中的
    const item = downingList.value.find(item => item.status === '0')
    if (item) {
      startItem(item.id);
    }
  }

  const deleteDowningListItem = (id: string) => {//删除下载中的item
    const index = downingList.value.findIndex(item => item.id === id)
    const item = downingList.value.find(item => item.id === id)
    if (item) {
      downingListDB.delete(item.id)//删除db item
      clearItemDownloadEffect(item,isMember.value);
    }
    if (index !== -1) {
      downingList.value.splice(index, 1);
      autoAppend();
    }
  }

  const clearItemDownloadEffect = async (item: any,_isMember:boolean) => {//清除item上的下载副作用
    const itemClone={...toRaw(item)}
    if (_isMember) {//此时是会员
      if (itemClone.downloadId) {//已经开始下载，清除下载
        await invokeAsyncAPi('fq_ctrl_download', {//删除创建下载器
          id: itemClone.downloadId,
          url:itemClone.realUrl,
          flag:2,
        })
      } else if (itemClone.downloadRealId) {//此时没有下载，但是之前创建过的下载器
        await invokeAsyncAPi('fq_clear_old_download', {//删除没创建任务的下载器
          id: itemClone.downloadRealId,
          save_path:itemClone.downloadPath
        })
      }
    } else {//此时不是会员
      if (itemClone.downloadId) {//开始下载了，清除fake定时器
        fakeDownloadInstance.deleteOne(itemClone.downloadId)
      }
      if (itemClone.downloadRealId) {//之前会员的时候，曾经创建过一个下载器，删除
        await invokeAsyncAPi('fq_clear_old_download', {//删除没创建任务的下载器
          id: itemClone.downloadRealId,
          save_path:itemClone.downloadPath
        })
      }
    }
  }

  const deleteAllDowningListItem = () => {//删除所有下载中的List
    for (const item of downingList.value) {
      //删除所有的下载器器
      clearItemDownloadEffect(item,isMember.value);
    }
    downingList.value = [];
    downingListDB.clear('downloadManage');
  }

  const deleteAllFinishDownloadListItem = () => {//删除所有下载完成的列表
    finishList.value = [];
    downloadFinishDB.clear('downloadManage');
  }

  const stopAllDowningListItem = () => {//暂停所有下载中的
    for (const item of downingList.value) {
      stopItem(item.id,true);
    }
  }

  const startAllDowningListItem = () => {//开启下载
    for (const item of downingList.value) {
      startItem(item.id);
    }
  }

  const memberStatusChange = () => {//会员状态变更，切换下载对象
    let stopItemCount = 0;
    for (const item of downingList.value) {
      //删除所有的下载器器
      clearItemDownloadEffect(item,!isMember.value);//清除变化之前的状态
      item.downloadId = '';
      if (['1', '5'].includes(item.status)) {
        item.status = '4';
        stopItemCount++;
        if (isMember.value) {//非会员变成会员，直接下载
           startItem(item.id);
        }
      } 
    }
    //还有剩余名额，全部开启
    if (isMember.value && stopItemCount < maxDownloadSize) {
      const leafCount = maxDownloadSize - stopItemCount;
      let _count = 0;
      for (const item of downingList.value) {
        if (item.status === '4'&&_count<leafCount) {
          _count++;
          startItem(item.id);
        }
      }
    }
    if (!isMember.value&&stopItemCount) {//会员->非会员，弹出框
      dialog.showDialog('memberChange').then(() => {
      }).catch((value) => {
        if (value === 'member') {
          invokeAsyncAPi('fq_ShowUserCenter')
        }
      })
    }
  }
  

  const deleteDownloadFinishItem = (id: string) => {//删除下载完成的item
    const index = finishList.value.findIndex(item => item.id === id)
    const item = finishList.value.find(item => item.id === id)
    if (item) {
      downloadFinishDB.delete(item.id)//删除db item
    }
    if (index !== -1) {
      finishList.value.splice(index, 1);
    }
  }


  const sendDowningDataToManageWindow = () => {//发送数据到管理页码
    const oldDowningList = [...toRaw(downingList.value)]
    if (downloadManageWindowId.value) {//window存在
      invokeAsyncAPi('fq_NotifyWebMessageEx', downloadManageWindowId.value, 'download-manage-downing-table-list',oldDowningList);
    }
  }

  const sendFinishDownloadDataToManageWindow = () => {
    const oldfinishList = [...toRaw(finishList.value)]
    if (downloadManageWindowId.value) {//window存在
      invokeAsyncAPi('fq_NotifyWebMessageEx', downloadManageWindowId.value, 'download-manage-finish-table-list',oldfinishList);
    }
  }

  const sendFinishDownloadRedFlagToManageWindow = () => {//下载完成小红点同步
    if (downloadManageWindowId.value) {//window存在
      invokeAsyncAPi('fq_NotifyWebMessageEx', downloadManageWindowId.value, 'download-manage-finish-red-flag',downloadFinishRedFlag.value);
    }
  }

  

  //同步到子窗口的store
  watch(downingList, (value) => {
    sendDowningDataToManageWindow();
  }, {
    deep:true
  })

  watch(finishList, (value) => {
    sendFinishDownloadDataToManageWindow();
  }, {
    deep:true
  })

  watch(downloadFinishRedFlag, (value) => {
    sendFinishDownloadRedFlagToManageWindow();
  })

  //从db同步的时候，使用
  function setDowningList(list:any[]) {
    downingList.value = list;
  }
  function setFinishList(list:any[]) {
    finishList.value = list;
  }

  //清除小红点
  const resetDowningRedFlag = () => {
    downingRedFlag.value = false;
    downingShowTipIsFirst.value = false;
    localStorage.setItem('downingShowTipHasShow', 'true')
    downingShowTip.value = false;
  }
  const resetDownloadFinishRedFlag = () => {
    downloadFinishRedFlag.value = false;
  }

  //清除所有下载器
  // const clearAllDowning = () => {
  //   if (isMember.value) {
  //     for (const item of downingList.value) {
  //       //删除所有的下载器器
  //       if (item.downloadId) {
  //         invokeAsyncAPi('fq_ctrl_download', {//删除下载器
  //           id: item.downloadId,
  //           url:item.realUrl,
  //           flag:2,
  //         })
  //         item.downloadId = '';
  //       }
  //       item.status = '4';
  //       downingListDB.put({ ...toRaw(item) })
  //     }
  //   } else {
  //     for (const item of downingList.value) {
  //       //删除所有的下载器器
  //       if (item.downloadId) {
  //         fakeDownloadInstance.deleteOne(item.downloadId)
  //         item.downloadId = '';
  //       }
  //       item.status = '4';
  //       downingListDB.put({ ...toRaw(item) })
  //     }
  //   }
  // }


  return {
    downingList,
    finishList,
    downingRedFlag,
    downingShowTip,
    downloadFinishRedFlag,
    addToDowningList,
    processDowningItem,
    finishDowningItem,
    deleteDowningListItem,
    deleteAllFinishDownloadListItem,
    deleteDownloadFinishItem,
    deleteAllDowningListItem,
    stopAllDowningListItem,
    startAllDowningListItem,
    startItem,
    stopItem,
    sendDowningDataToManageWindow,
    sendFinishDownloadDataToManageWindow,
    sendFinishDownloadRedFlagToManageWindow,
    setDowningList,
    setFinishList,
    resetDowningRedFlag,
    resetDownloadFinishRedFlag,
    memberStatusChange
  }
})
